package com.huwaiwai.threadpool;


import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Created by hww on 2018/7/7 上午12:10.
 */
public class Test {

    public static void main(String [] args) {
        testThreadPool();
    }

    /**
     * 测试线程池任务分配逻辑
     * 1.启用核心线程处理任务
     * 2.核心线程分配完毕，新任务进入队列
     * 3.队列放满后，启动非核心线程处理任务
     * 4.核心线程数+非核心线程数达到线程池容量后，执行任务拒绝策略
     */
    private static void testThreadPool() {
        ThreadPoolExecutor executorService = new ThreadPoolExecutor(1, 2,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(1));
        int core = executorService.getCorePoolSize();
        // 线程池初始化后 core = 1， activieCount = 0
        System.out.println("初始化后的核心线程数=" + core);
        System.out.println("初始化后的活跃线程数= " + executorService.getActiveCount());
        System.out.println("初始化后任务队列任务数=" + executorService.getQueue().size());

        // 放入第一个任务 任务会执行一秒钟 确保执行任务的线程 在main方法结束时 还未释放
        // 线程池会分配核心线程去处理这个任务
        executorService.execute(new ThreadPoolSize());
        // 此时 活跃线程数=1
        System.out.println("提交第一个任务后活跃线程数=" + executorService.getActiveCount());
        System.out.println("提交一个任务后任务队列任务数=" + executorService.getQueue().size());

        // 放入第二个任务 由于第一个任务还没执行完，无核心线程可用，任务将放入队列中等待
        executorService.execute(new ThreadPoolSize());
        // 此时 活跃线程数=1，队列长度=1
        System.out.println("提交第二个任务后活跃线程数=" + executorService.getActiveCount());
        System.out.println("提交第二个任务后任务队列任务数=" + executorService.getQueue().size());

        // 放入第三个任务 由于第一个任务都没执行完，无核心线程可用，且此时队列已满 将创建非核心线程来处理当前任务
        executorService.execute(new ThreadPoolSize());
        // 此时 活跃线程数=2，队列长度=1
        System.out.println("提交第三个任务后活跃线程数=" + executorService.getActiveCount());
        System.out.println("提交第三个任务后任务队列任务数=" + executorService.getQueue().size());

        // 放入第四个任务 由于第一个任务还没执行完成，无核心线程可用  且此时队列已满 将创建非核心线程来处理当前任务
        // 但是由于线程数已经达到线程池的最大限度  此任务只能执行拒绝策略
        try {
            executorService.execute(new ThreadPoolSize());
        } catch (RejectedExecutionException executionException) {
            System.out.println("接收到拒绝异常");
        }
    }

    /**
     * 测试 注册自定义处理器  处理 未被线程正常捕获的异常
     */
    private static void testUncaughtExceptionHandler() {
        Thread thread = new Thread(() -> {
            int i = 1/0;
        });
        // 注册自定义处理器，用于处理线程抛出的未被正常捕获的异常
        thread.setUncaughtExceptionHandler((t, e) -> System.out.println("in handler"));
        thread.start();
    }


    /**
     * 测试 synchronized关键字 锁定的是对象本身
     * 不同线程调用同一个对象的 不用同步方法 会阻塞 前面一个执行完毕后才能执行下一个
     * 同一个线程可以嵌套执行同步方法
     */
    private static void testSync() {
        final Synchronized s = new Synchronized();
        new Thread(() -> {
            try {
                s.method01(Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        new Thread(() -> {
            try {
                s.method02(Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        System.out.println("main end");
    }
}


class Synchronized {
    synchronized void method01(String threadName) throws InterruptedException {
        System.out.println(threadName + " do method01 start");
        Thread.sleep(1000L);
        System.out.println(threadName + " do method01 end");
        method02(threadName);
    }
    synchronized void method02(String threadName) throws InterruptedException {
        System.out.println(threadName + " do method02 start");
        Thread.sleep(1000L);
        System.out.println(threadName + " do method02 end");
    }
}

class ThreadPoolSize implements Runnable {

    @Override
    public void run() {
        try {
            Thread.sleep(1000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
